﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace Steganograf
{
    public partial class frmMain : Form
    {
        public frmMain()
        {
            InitializeComponent();
            SetButtonsEnabled(false, true, false, false);
        }

        private void btnOriginal_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDlg = new OpenFileDialog();
            openFileDlg.Multiselect = false;
            openFileDlg.Filter = "Windows Bitmap (*.bmp)|*.bmp";
            if (openFileDlg.ShowDialog(this) != DialogResult.Cancel)
            {
                txtOriginal.Text = openFileDlg.FileName;
                m_StegoFile = null;
                picStegoFile.Image = null;

                Image picture = new Bitmap(txtOriginal.Text);
                FitPicture(picture, picOriginal);
                picOriginal.Image = new Bitmap(picture);
                picture.Dispose();
            }
            SetButtonsEnabled(true, true, true, false);
        }

        private void btnHide_Click(object sender, EventArgs e)
        {
            string pic = txtOriginal.Text;
            string message = txtMessage.Text;
            string password = txtPassword.Text;

            if (String.IsNullOrWhiteSpace(pic))
            {
                Error("Wybierz plik źródłowy");
                return;
            }

            if(String.IsNullOrWhiteSpace(message))
            {
                Error("Wpisz wiadomość do ukrycia");
                return;
            }

            if (String.IsNullOrEmpty(password))
            {
                Error("Podaj hasło do zaszyfrowania wiadomości");
                return;
            }

            try
            {
                BmpOrigFile myFile = new BmpOrigFile(pic);
                histogramOriginal.DrawHistogram(new Bitmap(Bitmap.FromFile(pic)));

                m_StegoFile = myFile.CreateStegoFile(message, password);
                Info("Wiadomość zagnieżdżona pomyślnie");

                Image stegoPic = m_StegoFile.Bitmap;
                FitPicture(stegoPic, picStegoFile);
                picStegoFile.Image = new Bitmap(stegoPic);
                //stegoPic.Dispose();

                histogramStego.DrawHistogram((Bitmap)picStegoFile.Image);

                SetButtonsEnabled(true, true, true, true);
            }
            catch (Exception ex)
            {
                Error(ex.Message);
            }
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            SaveFileDialog saveFileDlg = new SaveFileDialog();
            saveFileDlg.Filter = "Windows Bitmap (*.bmp)|*.bmp";
            if (saveFileDlg.ShowDialog(this) != DialogResult.Cancel)
            {
                string stegoFileName = saveFileDlg.FileName;
                if (!stegoFileName.ToLower().EndsWith(".bmp"))
                    stegoFileName += ".bmp";

                try
                {
                    m_StegoFile.SaveToFile(stegoFileName);
                }
                catch(Exception ex)
                {
                    Error(ex.Message);
                }
            }
        }

        private void btnRead_Click(object sender, EventArgs e)
        {
            string password = txtPassword.Text;

            if (String.IsNullOrEmpty(password))
            {
                Error("Podaj hasło do odszyfrowania wiadomości");
                return;
            }

            try
            {
                if (picStegoFile.Image == null)
                {
                    if (String.IsNullOrWhiteSpace(txtOriginal.Text))
                    {
                        Error("Brak pliku źródłowego do odczytu wiadomości");
                        return;
                    }
                    m_StegoFile = new BmpStegoFile(txtOriginal.Text);
                }
                txtMessage.Text = "";
                txtMessage.Text = m_StegoFile.GetHiddenMessage(password);
            }
            catch
            {
                Error("Brak wiadomości lub plik źródłowy nieprawidłowy");
            }
        }

        private void btnCorrect_Click(object sender, EventArgs e)
        {
            Dictionary<string, int> diff = histogramStego.CountHistogramDifferences(histogramOriginal.HistogramValues);
            m_StegoFile.CorrectHistogram(diff, new Bitmap(txtOriginal.Text));

            Image stegoPic = m_StegoFile.Bitmap;
            FitPicture(stegoPic, picStegoFile);
            picStegoFile.Image = new Bitmap(stegoPic);

            histogramStego.DrawHistogram((Bitmap)picStegoFile.Image);
        }

        private void FitPicture(Image pic, PictureBox box) //TODO
        {
            box.Width = 350;    //default form picturebox size
            box.Height = 350;

            int width = pic.Width;
            int height = pic.Height;

            if (width > height)
            {
                int size = box.Width;
                int x = height * size / width;
                box.Height = x;
            }
            else
            {
                int size = box.Height;
                int x = width * size / height;
                box.Width = x;
            }
        }

        private void SetButtonsEnabled(bool pHideEnabled, bool pOriginalEnabled, bool pReadEnabled, bool pSaveEnabled)
        {
            btnHide.Enabled = pHideEnabled;
            btnOriginal.Enabled = pOriginalEnabled;
            btnRead.Enabled = pReadEnabled;
            btnSave.Enabled = pSaveEnabled;
        }

        private void Error(string pMsg)
        {
            MessageBox.Show(pMsg, "Steganograf - ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        private void Info(string pMsg)
        {
            MessageBox.Show(pMsg, "Steganograf - INFO", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        private BmpStegoFile m_StegoFile = null;
    }
}
